package com.zmn.oms.business.impl.graborder;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.graborder.GrabOrderBService;
import com.zmn.oms.common.constant.OrderDistributeConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.constant.MessageQueueTopicConstant;
import com.zmn.oms.manager.utils.MongodbConsts;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.dto.graborder.MqGrabOrderDTO;
import com.zmn.oms.model.mongo.graborder.GrabOrder;
import com.zmn.oms.model.mongo.graborder.GrabOrderQuery;
import com.zmn.oms.services.interfaces.graborder.GrabOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 类描述：抢单
 *
 * @author liuying
 * @date 2021/07/13 11:17
 */
@Slf4j
@Service
public class GrabOrderBServiceImpl implements GrabOrderBService {

    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private GrabOrderService grabOrderService;
    @Resource
    private ZmnMQSender zmnMQSender;
    @Resource
    private RedisManager redisManager;

    @Override
    public List<GrabOrder> listGrabOrderByQuery(GrabOrderQuery grabOrderQuery) {
        Objects.requireNonNull(grabOrderQuery);
        Objects.requireNonNull(grabOrderQuery.getCategIdList());

        log.debug("grabOrderQuery={}", JSON.toJSONString(grabOrderQuery));

        Query query = new Query();
        query.addCriteria(Criteria.where("manageCompanyId").in(new Integer[]{grabOrderQuery.getManageCompanyId(), GlobalConsts.NONE}));
        query.addCriteria(Criteria.where("gridCompanyId").in(new Integer[]{grabOrderQuery.getGridCompanyId(), GlobalConsts.NONE}));
        query.addCriteria(Criteria.where("cityId").is(grabOrderQuery.getCityId()).and("grabStatus").is(GlobalConsts.NO));
        if (Objects.nonNull(grabOrderQuery.getAgent())) {
            query.addCriteria(Criteria.where("agent").in(new Integer[]{grabOrderQuery.getAgent(), GlobalConsts.NONE}));
        } else {
            query.addCriteria(Criteria.where("agent").is(GlobalConsts.NONE));
        }

        if (CollectionUtils.isNotEmpty(grabOrderQuery.getServCategIdList())) {
            query.addCriteria(Criteria.where("servCategId").in(grabOrderQuery.getServCategIdList()));
        }
        if (CollectionUtils.isNotEmpty(grabOrderQuery.getCategIdList())) {
            query.addCriteria(Criteria.where("categId").in(grabOrderQuery.getCategIdList()));
        }
        query.addCriteria(Criteria.where("bizType").in(grabOrderQuery.getBizTypeList()));

        // 师傅服务范围查询
        /*List<Criteria> criteriaServiceAreaList = Lists.newArrayList();

        // 多边型地图
        if (CollectionUtils.isNotEmpty(grabOrderQuery.getServiceAreaPolygonList())) {
            grabOrderQuery.getServiceAreaPolygonList().forEach(pointList -> {
                criteriaServiceAreaList.add(Criteria.where("location").intersects(new GeoJsonPolygon(pointList)));
            });
        }

        // 圆型地图
        if (CollectionUtils.isNotEmpty(grabOrderQuery.getServiceAreaCircleList())) {
            grabOrderQuery.getServiceAreaCircleList().forEach(circle -> {
                criteriaServiceAreaList.add(Criteria.where("location").within(circle));
            });
        }

        // 城市
        if (CollectionUtils.isNotEmpty(grabOrderQuery.getServiceAreaCityIdList())) {
            criteriaServiceAreaList.add(Criteria.where("cityId").in(grabOrderQuery.getServiceAreaCityIdList()));
        }

        // 区域
        if (CollectionUtils.isNotEmpty(grabOrderQuery.getServiceAreaCountyIdList())) {
            criteriaServiceAreaList.add(Criteria.where("countyId").in(grabOrderQuery.getServiceAreaCountyIdList()));
        }

        // 街道
        if (CollectionUtils.isNotEmpty(grabOrderQuery.getServiceAreaStreetIdList())) {
            criteriaServiceAreaList.add(Criteria.where("streetId").in(grabOrderQuery.getServiceAreaStreetIdList()));
        }*/

        // 服务范围查询
        ArrayList<Criteria> criteriaList = Lists.newArrayList();

        // 师傅服务范围查询
        /*if (CollectionUtils.isNotEmpty(criteriaServiceAreaList)) {
            criteriaList.add(Criteria.where("distributeWay").in(OrderDistributeConsts.DISTRIBUTE_WAY_SP)
                    .andOperator(new Criteria().orOperator(criteriaServiceAreaList.toArray(new Criteria[0]))));
        }*/
        criteriaList.add(Criteria.where("distributeWay").in(OrderDistributeConsts.DISTRIBUTE_WAY_SP));

        // 师傅网格服务范围查询
        if (CollectionUtils.isNotEmpty(grabOrderQuery.getGridList())) {
            criteriaList.add(Criteria.where("distributeWay").in(OrderDistributeConsts.DISTRIBUTE_WAY_PLAT)
                    .andOperator(Criteria.where("gridId").in(grabOrderQuery.getGridList())));
        }

        if (CollectionUtils.isNotEmpty(criteriaList)) {
            query.addCriteria(new Criteria().orOperator(criteriaList.toArray(new Criteria[0])));
        }

        query.with(Sort.by(Sort.Order.desc("createTime"))).limit(50);

        log.debug("GrabOrderBServiceImpl#listGrabOrderByQuery query => {}", query.toString());
        List<GrabOrder> list = mongoTemplate.find(query, GrabOrder.class, MongodbConsts.OMS_GRAB_ORDER);
        log.debug("GrabOrderBServiceImpl#listGrabOrderByQuery => {}", query.toString());

        return list;
    }

    @Override
    @Transactional
    public void saveGrabOrderByOrderId(GrabOrder grabOrder) throws OmsBaseException {
        String key = "grab-" + grabOrder.getWorkId();
        MqGrabOrderDTO dto = new MqGrabOrderDTO();
        dto.setWorkId(grabOrder.getWorkId());
        long dateTime = System.currentTimeMillis();
        dto.setDateTime(dateTime);
        String message = JSON.toJSONString(dto);
        long time = grabOrder.getGrabEndTime().getTime();
        if (dateTime >= time) {
            throw new OmsBaseException("已过抢单时间");
        } else {
            grabOrderService.saveGrabOrder(grabOrder);
            zmnMQSender.sendWithStartDeliverTime(MessageQueueTopicConstant.ZMN_TOPIC_OMS, OmsMqTagConsts.GRAB_ORDER_END_TIME_MQ_TAG, key, message, time);
        }
        String redisKey = String.format(RedisKeyConsts.GRAB_CONSUME_ORDER_KEY, grabOrder.getWorkId());
        // 一天=86400秒，过期时间3天
        redisManager.setex(redisKey, String.valueOf(dateTime), 86400 * 3);
    }

    /**
     * 更新抢单信息
     *
     * @param grabOrder
     */
    @Override
    public void updateGrabOrderByOrderId(GrabOrder grabOrder) {
        grabOrderService.saveGrabOrder(grabOrder);
    }

}
